package iterator;

import utils.NumberUtil;
import constants.NumberConstants;
import data.Player;

public class IterativeRank implements Comparable<IterativeRank> {
	private double rank;
	private double rankToAdd;
//	private double lastGain = 0;
	private Player player;
	private boolean print = true;
	public IterativeRank (Player player){
		this.player = player;
		rank = NumberConstants.STARTING_RANK;
		rankToAdd = 0;
	}
	public void addRank(double rank){
		rankToAdd += rank;
//		lastGain = rankToAdd;
	}
	public void subRank(double rank){
		rankToAdd -= rank;
	}
	public void gainPoints(IterativeRank loserRank, int totalRank){
		this.gainPoints(loserRank, totalRank, 1);
	}
	public void gainPoints(IterativeRank loserRank, int totalRank, double factor){
		double difference = this.rank - loserRank.rank;
		double differenceMultiplier =  1-difference/totalRank;
		double rankTransfer = loserRank.rank*NumberConstants.FRACTION*differenceMultiplier * factor;
		addRank(rankTransfer);
		loserRank.subRank(rankTransfer);
		if (IterativeRanker.last && print)
			System.out.println("win," + this.player + "," + loserRank.player + "," + rankTransfer + "," + factor);
	}
	public void transferPointsTie(IterativeRank other){
		this.transferPointsTie(other, 1);
	}
	public void transferPointsTie(IterativeRank other, double factor){
		double transfer = (other.rank - this.rank) * NumberConstants.FRACTION * factor;
		this.addRank(transfer);
		other.subRank(transfer);
		if (IterativeRanker.last && print){
			if (transfer>0)
				System.out.println("fix," + this.player + "," + other.player + "," + transfer + "," + factor);
			else
				System.out.println("fix," + other.player + "," + this.player + "," + (-1*transfer) + "," + factor);
		}
			
	}
	/**
	 * @return Rank changed
	 */
	public boolean applyRank(){
		rank  += rankToAdd;
		if (rank<=0)
			rank = 0;
		boolean changed = false;
		if (rankToAdd<0)
			rankToAdd *= -1;
		if (rankToAdd>=NumberConstants.MIN_CHANGE)
			changed = true;
		if (rank<5)
			rank = (int) rank;
		rankToAdd = 0;
		return changed;
	}
	public double getRank() {
		return rank;
	}
	public String toString(){
		return  NumberUtil.roundDoubleToDigits(rank, 2) + " " + player;
	}
	@Override
	public int compareTo(IterativeRank o) {
		if (this.rank>o.rank)
			return -1;
		if (o.rank>this.rank)
			return 1;
		return 0;
	}
}
